import { fetchAdapter, abortCtrBucket } from './adapters'
import { IHook, IOptions, IRequestHook, IResponse, IResponseHook, Ictr } from './types'

export class BaseRequest {
  public initCtr: Ictr
  public initOptions: IOptions
  public requestHooks: IRequestHook[]
  public responseHooks: IResponseHook[]
  static abortCtrBucket = abortCtrBucket
  constructor(initOptions: IOptions, requestHooks: IRequestHook[], responseHooks: IResponseHook[], initCtr: Ictr) {
    this.initOptions = initOptions
    this.requestHooks = requestHooks
    this.responseHooks = responseHooks
    this.initCtr = initCtr
  }
  async request(url: string, options: IOptions, ctr?: Ictr) {
    // 合并默认参数
    options = Object.assign({}, this.initOptions, options)
    ctr = Object.assign({}, this.initCtr, ctr)
    // 请求前中间件处理
    for (let mid of this.requestHooks) {
      const reqTemp = await mid({ url, options, ctr })
      // 如果返回的值含有 breakName，则直接返回不在执行后续中间件
      if (reqTemp && Reflect.has(reqTemp, 'breakName')) return reqTemp.data
    }

    let originalData: IResponse = { status: 'pending', data: null }
    try {
      const data = await fetchAdapter(url, options)
      // console.log(data, '-->>> data')
      originalData.status = 'success'
      originalData.data = data
    } catch (error) {
      // console.log(error, '-->>> error')
      originalData.status = 'error'
      originalData.data = error
    }
    let result: any = originalData.data
    // 请求后中间件处理
    for (let mid of this.responseHooks) {
      const resTemp = await mid({ url, options, originalData, result, ctr })
      if (resTemp !== undefined) {
        result = resTemp
      }
    }
    return result
  }
}
